package com.alinesno.cloud.gateway.core.dispather.mina.client;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.ReadFuture;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alinesno.cloud.gateway.core.dispather.mina.bean.BusinessServerBean;
import com.alinesno.cloud.gateway.core.dispather.mina.bean.MessageBean;
import com.alinesno.cloud.gateway.core.dispather.mina.codec.MessageCodeFactory;
import com.alinesno.cloud.gateway.core.dispather.mina.exception.MinaConnectTimeoutException;

/**
 * 对于mina客户端同步操作来说，长连接变换为短连接，即客户端的每次操作都需要建立连接，发送消息，接收消息，断开连接
 * 
 * @author WeiXiaoJin
 * @since 2020年1月31日 下午19:45:08
 */
public class MinaClient {

	@SuppressWarnings("unused")
	private static final Logger log = LoggerFactory.getLogger(MinaClient.class);

	private static final int DEFAULT_CLIENT_OUTTIME = 45 ; 
	
	/**
	 * 发送报文消息
	 * 
	 * @param message
	 * @return
	 * @throws MinaConnectTimeoutException
	 */
	public static MessageBean send(MessageBean message, BusinessServerBean server) {

		String SERVER_IP = server.getForwardIp() ; 
		int PORT = server.getForwardPort() ;
		
		NioSocketConnector connector = new NioSocketConnector(); // 连接对象
		connector.setConnectTimeoutMillis(30000L); // 设置连接超时时间
		connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MessageCodeFactory(server))); // 自定义解码器
		IoSession session = null;

		try {
			
			SocketSessionConfig cfg = connector.getSessionConfig();
			cfg.setUseReadOperation(true); // 实现同步的mina客户端必须设置UseReadOperation属性为true
			
			connector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, server.getClientOuttime()==0?DEFAULT_CLIENT_OUTTIME:server.getClientOuttime());
			connector.setDefaultRemoteAddress(new InetSocketAddress(SERVER_IP, PORT));// 设置默认访问地址
			ConnectFuture future = connector.connect();
			future.awaitUninterruptibly(); // 等待连接创建成功
			session = future.getSession(); // 获取会话

			if (!session.isConnected()) {
				throw new MinaConnectTimeoutException("连接SOCKET服务异常,请检查SOCKET端口、IP是否正确,MSG服务是否启动");
			}
			session.write(message).awaitUninterruptibly(); // 发送

			ReadFuture readFuture = session.read(); // 接收
			
			Object response = null ; 
			if(readFuture.awaitUninterruptibly(90, TimeUnit.SECONDS)){ //Wait until the message is received  
				response = readFuture.getMessage();                    //Get the received message  
			} 
			if(response != null) {
				if (response instanceof MessageBean) {
					return (MessageBean) response;
				}
			}
			
		} catch (MinaConnectTimeoutException e) {
			e.printStackTrace();
		} finally {
			session.closeOnFlush();
			session.getService().dispose();
			connector.dispose();
		}

		return null;
	}

}